Skip to content

개요

Timefit 예약 관리 시스템의 업체 정보 관리, 영업시간 설정, 예약 가능 시간 슬롯 관리를 위한 API입니다. 업체 프로필 관리, 서비스 메뉴 설정, 운영 시간 관리 기능을 제공합니다.

API 목록

구분API 명설명
프로필 관리업체 정보 조회업체의 프로필 정보를 조회합니다
프로필 관리업체 정보 수정업체의 프로필 정보를 수정합니다
운영 관리영업시간 설정업체의 영업시간을 설정합니다
운영 관리영업시간 조회업체의 영업시간을 조회합니다
예약 관리예약 가능 시간 설정예약 가능한 시간대를 설정합니다
예약 관리예약 가능 시간 조회예약 가능한 시간대를 조회합니다
서비스 관리서비스 메뉴 등록제공하는 서비스/메뉴를 등록합니다
서비스 관리서비스 메뉴 조회등록된 서비스/메뉴를 조회합니다
서비스 관리서비스 메뉴 수정서비스/메뉴 정보를 수정합니다
서비스 관리서비스 메뉴 삭제서비스/메뉴를 삭제합니다

1. 업체 정보 조회

업체의 프로필 정보를 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/profile \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/businesses/{businessId}/profile

Request Header

파라미터타입필수여부설명
AuthorizationString필수Bearer

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4-a716-446655440001

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "업체 정보 조회가 완료되었습니다",
  "data": {
    "businessId": "660e8400-e29b-41d4-a716-446655440001",
    "businessName": "홍길동 미용실",
    "businessType": "미용실",
    "businessNumber": "123-45-67890",
    "address": "서울시 강남구 테헤란로 123",
    "contactPhone": "0212345678",
    "description": "깔끔하고 세련된 미용실입니다",
    "logoUrl": "<https://example.com/logo.jpg>",
    "createdAt": "2024-06-07T12:30:00Z",
    "updatedAt": "2024-06-07T12:30:00Z",
    "members": [
      {
        "userId": "550e8400-e29b-41d4-a716-446655440000",
        "email": "business@example.com",
        "name": "홍길동",
        "phoneNumber": "01012345678",
        "profileImageUrl": "<https://example.com/profile.jpg>",
        "role": "OWNER",
        "joinedAt": "2024-06-07T12:30:00Z",
        "invitedBy": null,
        "isActive": true
      },
      {
        "userId": "551e8400-e29b-41d4-a716-446655440002",
        "email": "manager@example.com",
        "name": "김매니저",
        "phoneNumber": "01087654321",
        "profileImageUrl": null,
        "role": "MANAGER",
        "joinedAt": "2024-06-10T15:20:00Z",
        "invitedBy": "550e8400-e29b-41d4-a716-446655440000",
        "isActive": true
      }
    ],
    "userRole": "OWNER"
  }
}

Response Elements

필드타입필수여부설명
businessIdstring필수업체 ID (UUID)
businessNamestring필수상호명
businessTypestring선택업종
businessNumberstring필수사업자번호
addressstring선택업체 주소
contactPhonestring선택업체 연락처
descriptionstring선택업체 설명
logoUrlstring선택로고 이미지 URL
createdAtstring필수업체 등록일시 (ISO 8601)
updatedAtstring필수업체 수정일시 (ISO 8601)
membersarray필수업체 구성원 목록
members[].userIdstring필수사용자 ID
members[].emailstring필수사용자 이메일
members[].namestring필수사용자 이름
members[].phoneNumberstring선택사용자 연락처
members[].profileImageUrlstring선택프로필 이미지 URL
members[].rolestring필수업체 내 역할 (OWNER, MANAGER, MEMBER)
members[].joinedAtstring필수참여일시
members[].invitedBystring선택초대자 사용자 ID
members[].isActiveboolean필수활성화 상태
userRolestring필수요청자의 해당 업체에서의 역할

Error Response

에러 코드상태 코드메시지발생 상황
BUSINESS_NOT_FOUND404"업체 정보를 찾을 수 없습니다"존재하지 않는 업체
ACCESS_DENIED403"접근 권한이 없습니다"업체 구성원이 아님
TOKEN_EXPIRED401"토큰이 만료되었습니다"JWT 토큰 만료
TOKEN_INVALID401"유효하지 않은 토큰입니다"JWT 토큰 검증 실패

2. 업체 정보 수정

업체의 프로필 정보를 수정합니다.

Request

Request Syntax

bash
curl -X PUT https://{SERVER_URL}/api/businesses/{businessId}/profile \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "businessName": "홍길동 프리미엄 미용실",
    "businessType": "미용실",
    "address": "서울시 강남구 테헤란로 456",
    "contactPhone": "0287654321",
    "description": "최고급 서비스를 제공하는 프리미엄 미용실입니다",
    "logoUrl": "<https://example.com/new-logo.jpg>"
  }'
메서드요청 URL
PUThttps://{SERVER_URL}/api/businesses/{businessId}/profile

Request Header

파라미터타입필수여부설명
AuthorizationString필수Bearer
Content-TypeString필수application/json

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4-a716-446655440001

Request Elements

필드타입필수설명예시제약사항
businessNamestringN상호명홍길동 프리미엄 미용실2자 이상
businessTypestringN업종미용실-
addressstringN사업장 주소서울시 강남구...200자 이하
contactPhonestringN업체 대표 연락처0287654321-
descriptionstringN업체 설명최고급 서비스를...1000자 이하
logoUrlstringN로고 이미지 URLhttps://example.com...URL 형식

Response

Response Syntax (200 OK)

업체 정보 조회와 동일한 응답 구조를 반환합니다.

Error Response

에러 코드상태 코드메시지발생 상황
BUSINESS_NOT_FOUND404"업체 정보를 찾을 수 없습니다"존재하지 않는 업체
ACCESS_DENIED403"접근 권한이 없습니다"OWNER 또는 MANAGER 권한 필요
VALIDATION_ERROR400"입력값이 올바르지 않습니다"필드 검증 실패
BUSINESS_NUMBER_ALREADY_EXISTS409"이미 등록된 사업자번호입니다"사업자번호 중복 (변경 시)

3. 영업시간 조회

업체의 영업시간을 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/hours \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/businesses/{businessId}/hours

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4-a716-446655440001

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "영업시간 조회가 완료되었습니다",
  "data": {
    "businessId": "660e8400-e29b-41d4-a716-446655440001",
    "businessName": "홍길동 미용실",
    "businessHours": [
      {
        "hourId": "cc0e8400-e29b-41d4-a716-446655440007",
        "dayOfWeek": 1,
        "dayName": "월요일",
        "openTime": "09:00",
        "closeTime": "18:00",
        "isClosed": false,
        "createdAt": "2024-06-07T12:30:00Z",
        "updatedAt": "2024-06-07T12:30:00Z"
      },
      {
        "hourId": "dd0e8400-e29b-41d4-a716-446655440008",
        "dayOfWeek": 0,
        "dayName": "일요일",
        "openTime": null,
        "closeTime": null,
        "isClosed": true,
        "createdAt": "2024-06-07T12:30:00Z",
        "updatedAt": "2024-06-07T12:30:00Z"
      }
    ]
  }
}

Response Elements

필드타입필수여부설명
hourIdstring필수영업시간 ID (UUID)
dayOfWeekinteger필수요일 (0=일요일, 1=월요일, ..., 6=토요일)
dayNamestring필수요일명
openTimestring선택영업 시작 시간 (HH:mm)
closeTimestring선택영업 종료 시간 (HH:mm)
isClosedboolean필수휴무 여부

4. 영업시간 설정

업체의 영업시간을 설정합니다.

Request

Request Syntax

bash
curl -X PUT https://{SERVER_URL}/api/businesses/{businessId}/hours \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "businessHours": [
      {
        "dayOfWeek": 1,
        "openTime": "09:00",
        "closeTime": "18:00",
        "isClosed": false
      },
      {
        "dayOfWeek": 0,
        "openTime": null,
        "closeTime": null,
        "isClosed": true
      }
    ]
  }'
메서드요청 URL
PUThttps://{SERVER_URL}/api/businesses/{businessId}/hours

Request Elements

필드타입필수설명예시제약사항
businessHoursarrayY영업시간 목록[]요일별 설정
businessHours[].dayOfWeekintegerY요일10~6 (0=일요일)
businessHours[].openTimestringN영업 시작 시간09:00HH:mm 형식
businessHours[].closeTimestringN영업 종료 시간18:00HH:mm 형식
businessHours[].isClosedbooleanY휴무 여부false-

Response

Response Syntax (200 OK)

영업시간 조회와 동일한 응답 구조를 반환합니다.


5. 예약 가능 시간 조회

업체의 예약 가능한 시간대를 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/available-slots?date=2024-06-15 \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/businesses/{businessId}/available-slots

Query Parameters

파라미터타입필수설명예시
datestringY조회할 날짜2024-06-15
serviceIdstringN특정 서비스 IDaa0e8400-e29b-41d4...

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약 가능 시간 조회가 완료되었습니다",
  "data": {
    "businessId": "660e8400-e29b-41d4-a716-446655440001",
    "date": "2024-06-15",
    "dayOfWeek": 6,
    "isBusinessOpen": true,
    "businessHours": {
      "openTime": "09:00",
      "closeTime": "18:00"
    },
    "availableSlots": [
      {
        "slotId": "ee0e8400-e29b-41d4-a716-446655440010",
        "startTime": "09:00",
        "endTime": "09:30",
        "duration": 30,
        "capacity": 1,
        "currentBookings": 0,
        "isAvailable": true,
        "price": null
      },
      {
        "slotId": "ff0e8400-e29b-41d4-a716-446655440011",
        "startTime": "09:30",
        "endTime": "10:00",
        "duration": 30,
        "capacity": 1,
        "currentBookings": 1,
        "isAvailable": false,
        "price": null
      }
    ]
  }
}

6. 예약 가능 시간 설정

업체의 예약 가능한 시간대를 설정합니다.

Request

Request Syntax

bash
curl -X PUT https://{SERVER_URL}/api/businesses/{businessId}/available-slots \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "date": "2024-06-15",
    "slots": [
      {
        "startTime": "09:00",
        "endTime": "09:30",
        "capacity": 1,
        "isAvailable": true
      },
      {
        "startTime": "09:30",
        "endTime": "10:00",
        "capacity": 1,
        "isAvailable": false
      }
    ]
  }'

Request Elements

필드타입필수설명예시제약사항
datestringY설정할 날짜2024-06-15YYYY-MM-DD
slotsarrayY시간 슬롯 목록[]-
slots[].startTimestringY시작 시간09:00HH:mm
slots[].endTimestringY종료 시간09:30HH:mm
slots[].capacityintegerY수용 인원11 이상
slots[].isAvailablebooleanY예약 가능 여부true-

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약 가능 시간이 설정되었습니다",
  "data": {
    "businessId": "660e8400-e29b-41d4-a716-446655440001",
    "date": "2024-06-15",
    "updatedSlots": [
      {
        "slotId": "ee0e8400-e29b-41d4-a716-446655440010",
        "startTime": "09:00",
        "endTime": "09:30",
        "capacity": 1,
        "isAvailable": true,
        "createdAt": "2024-06-07T12:30:00Z"
      }
    ],
    "totalSlots": 16,
    "availableSlots": 14,
    "updatedAt": "2024-06-07T12:30:00Z"
  }
}

7. 서비스 메뉴 조회

등록된 서비스/메뉴를 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/services \\
  -H "Authorization: Bearer {accessToken}"

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "서비스 메뉴 조회가 완료되었습니다",
  "data": {
    "businessId": "660e8400-e29b-41d4-a716-446655440001",
    "businessName": "홍길동 미용실",
    "services": [
      {
        "serviceId": "aa0e8400-e29b-41d4-a716-446655440005",
        "serviceName": "기본 커트",
        "description": "기본적인 헤어커트 서비스입니다",
        "price": 25000,
        "duration": 60,
        "category": "기본",
        "imageUrl": "<https://example.com/cut.jpg>",
        "isActive": true,
        "createdAt": "2024-06-07T12:30:00Z",
        "updatedAt": "2024-06-07T12:30:00Z"
      },
      {
        "serviceId": "bb0e8400-e29b-41d4-a716-446655440006",
        "serviceName": "프리미엄 염색",
        "description": "고급 염색 서비스입니다",
        "price": 80000,
        "duration": 180,
        "category": "프리미엄",
        "imageUrl": "<https://example.com/color.jpg>",
        "isActive": true,
        "createdAt": "2024-06-07T12:30:00Z",
        "updatedAt": "2024-06-07T12:30:00Z"
      }
    ],
    "totalCount": 2,
    "activeCount": 2
  }
}

8. 서비스 메뉴 등록

제공하는 서비스/메뉴를 등록합니다.

Request

Request Syntax

bash
curl -X POST https://{SERVER_URL}/api/businesses/{businessId}/services \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "serviceName": "기본 커트",
    "description": "기본적인 헤어커트 서비스입니다",
    "price": 25000,
    "duration": 60,
    "category": "기본",
    "imageUrl": "<https://example.com/cut.jpg>",
    "isActive": true
  }'

Request Elements

필드타입필수설명예시제약사항
serviceNamestringY서비스명기본 커트2자 이상
descriptionstringN서비스 설명기본적인...500자 이하
priceintegerY가격 (원)250000 이상
durationintegerY소요 시간 (분)6015분 단위
categorystringN카테고리기본-
imageUrlstringN서비스 이미지 URLhttps://...URL 형식
isActivebooleanN활성화 상태true기본값: true

Response

Response Syntax (201 Created)

json
{
  "success": true,
  "message": "서비스가 등록되었습니다",
  "data": {
    "serviceId": "aa0e8400-e29b-41d4-a716-446655440005",
    "serviceName": "기본 커트",
    "description": "기본적인 헤어커트 서비스입니다",
    "price": 25000,
    "duration": 60,
    "category": "기본",
    "imageUrl": "<https://example.com/cut.jpg>",
    "isActive": true,
    "displayOrder": 1,
    "createdAt": "2024-06-07T12:30:00Z",
    "updatedAt": "2024-06-07T12:30:00Z"
  }
}

9. 서비스 메뉴 수정

서비스/메뉴 정보를 수정합니다.

Request

Request Syntax

bash
curl -X PUT https://{SERVER_URL}/api/businesses/{businessId}/services/{serviceId} \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "serviceName": "프리미엄 커트",
    "description": "프리미엄 헤어커트 서비스입니다",
    "price": 35000,
    "duration": 90,
    "category": "프리미엄",
    "imageUrl": "<https://example.com/premium-cut.jpg>",
    "isActive": true
  }'

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4...
serviceIdstringY서비스 ID (UUID)aa0e8400-e29b-41d4...

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "서비스 정보가 수정되었습니다",
  "data": {
    "serviceId": "aa0e8400-e29b-41d4-a716-446655440005",
    "serviceName": "프리미엄 커트",
    "description": "프리미엄 헤어커트 서비스입니다",
    "price": 35000,
    "duration": 90,
    "category": "프리미엄",
    "imageUrl": "<https://example.com/premium-cut.jpg>",
    "isActive": true,
    "displayOrder": 1,
    "previousValues": {
      "serviceName": "기본 커트",
      "price": 25000,
      "duration": 60
    },
    "createdAt": "2024-06-07T12:30:00Z",
    "updatedAt": "2024-06-07T15:45:00Z"
  }
}

10. 서비스 메뉴 삭제

서비스/메뉴를 삭제합니다.

Request

Request Syntax

bash
curl -X DELETE https://{SERVER_URL}/api/businesses/{businessId}/services/{serviceId} \\
  -H "Authorization: Bearer {accessToken}"

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "서비스가 삭제되었습니다",
  "data": {
    "serviceId": "aa0e8400-e29b-41d4-a716-446655440005",
    "deletedAt": "2024-06-07T15:30:00Z"
  }
}

권한 체계

업체 내 역할별 권한

역할프로필 조회프로필 수정영업시간 관리서비스 관리멤버 관리
OWNER
MANAGER
MEMBER

권한 체크 로직

  1. JWT 토큰에서 사용자 ID 추출

  2. user_business_role 테이블에서 권한 확인:

    sql
    SELECT role FROM user_business_role WHERE user_id = ? AND business_id = ? AND is_active = true
  3. API별 필요 권한 검증

에러 응답

에러 코드상태 코드메시지발생 상황
BUSINESS_NOT_FOUND404"업체 정보를 찾을 수 없습니다"존재하지 않는 업체
ACCESS_DENIED403"접근 권한이 없습니다"권한 부족
INSUFFICIENT_PERMISSION403"해당 작업을 수행할 권한이 없습니다"역할별 권한 부족
USER_NOT_BUSINESS_MEMBER403"해당 업체의 구성원이 아닙니다"업체 구성원 아님

업체 관리 가이드

URL 구조 변경사항

기존신규변경사항
/api/business/profile/{userId}/api/businesses/{businessId}/profileuserId → businessId
사용자 기준비즈니스 기준권한 체계 완전 변경

권한 체크 변경사항

기존신규
business.user_id = ?user_business_role.user_id = ? AND business_id = ?
1:1 관계N:M 관계
단순 소유권역할 기반 권한

데이터 무결성

항목설명고려사항
영업시간-슬롯 일관성영업시간과 예약 슬롯 간 일관성 유지영업시간 외 슬롯 방지
서비스 삭제 영향서비스 삭제 시 관련 예약 데이터 영향 확인기존 예약 보호
가격 변경 영향가격 변경 시 기존 예약에 미치는 영향 고려예약 시점 가격 유지
멤버 권한 변경멤버 역할 변경 시 기존 작업에 미치는 영향권한 변경 이력 관리

비즈니스 규칙

  1. 소유자 필수: 모든 비즈니스는 최소 1명의 OWNER 필요
  2. 권한 위임: OWNER만 다른 사용자를 MANAGER로 승격 가능
  3. 데이터 접근: 활성화된 멤버만 비즈니스 데이터 접근 가능
  4. 영업시간 제약: 예약 슬롯은 영업시간 내에서만 설정 가능